const fs = require('fs');
const path = require('path');
const os = require('os');
const spawn = require('cross-spawn');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const I18nWebpackPlugin = require('@fiber/i18n-webpack-plugin');
const VueStyleInlinePlugin = require('@fiber/vue-style-inline-webpack-plugin');
const FiberSourceMapPlugin = require('@fiber/sourcemap-webpack-plugin');
const V5PcPlugin = require('./plugin/V5PcPlugin');
const noopPlugin = function () {};
const parseArgv = require('./parse-argv');
const getProxy = require('./get-proxy-config');
const options = parseArgv(true);
const baseExternals = { vue: 'Vue', axios: 'axios', vuex: 'Vuex', fiber: 'Fiber' };
const baseDir = path.resolve(__dirname, '../src/entries');
const isDev = process.env.NODE_ENV === 'development';
const isLib = options.target === 'lib';
const gitUser = getGitUser();
const builtTime = getTimeStr();

function getAssetsDir(dir) {
  return isDev ? dir : path.join(options.assetsDir, dir);
}

function getDevTemplate(dir) {
  const specConf = path.join(dir, 'xpack.json');
  if (fs.existsSync(specConf)) {
    const conf = require(specConf);
    if (conf.template) return path.join(dir, conf.template);
  }
  const specHtml = path.join(dir, 'index.html');
  if (fs.existsSync(specHtml)) {
    return specHtml;
  }
  return path.resolve(__dirname, 'dev-index.html');
}

// 生成打包页面的vue.config.js
function genAppConfig(config) {
  const pages = isDev ? fs.readdirSync(baseDir, { cwd: baseDir }) : [options.name];
  const entries = pages.reduce((pages, name) => {
    const workDir = path.join(baseDir, name);
    // NOTE: !!!不要指定chunks，开发模式下共享一个webpack实例，可能出现不确定名字的chunk
    pages[isDev ? name : 'app'] = {
      entry: path.join(workDir, 'main.js'),
      template: isDev ? getDevTemplate(workDir) : options.template,
      // html构建到 webapps/seeyon/ 下
      filename: isDev ? `${name}.html` : options.indexPath,
      title: options.title
    };
    return pages;
  }, {});

  // dev模式，添加默认首页
  if (entries.index) {
    throw new Error('子工程目录名不能为"index"');
  }
  if (isDev) {
    entries.index = {
      entry: path.join(__dirname, 'dev-index.js'),
      template: path.join(__dirname, 'dev-index.html'),
      filename: 'index.html',
      title: '调试首页',
      projects: pages
    };
  }

  return {
    pages: entries,
    publicPath: isDev ? '' : '/',
    assetsDir: isDev ? '' : options.assetsDir,
    outputDir: 'dist',
    devServer: {
      port: config.port || 3000,
      proxy: getProxy(config.proxyServer)
    },
    chainWebpack: (config) => {
      Object.keys(entries).forEach((name) => {
        config.plugins.delete(`preload-${name}`);
        config.plugins.delete(`prefetch-${name}`);
      });
    },
    configureWebpack: {
      externals: config.useFiber ? baseExternals : {},
      plugins: [
        new I18nWebpackPlugin({ inject: true, needHeaderJs: true }),
        new VueStyleInlinePlugin({ test: /css-loader/ }),
        new FiberSourceMapPlugin(),
        new V5PcPlugin(),
        isDev
          ? noopPlugin
          : new webpack.BannerPlugin({
              test: /\.(js|css)/,
              banner: `>>> built by ${gitUser} at ${builtTime}`
            }),
        isDev
          ? noopPlugin
          : new CopyWebpackPlugin(
              [
                {
                  context: path.join(baseDir, options.name),
                  from: 'static',
                  to: getAssetsDir('static')
                }
              ],
              { logLevel: 'error' }
            )
      ]
    }
  };
}

// 生成打包lib组件的vue.config.js
function genLibProdConfig() {
  const context = options.packDir;
  const columnFile = path.join(context, 'portal-column.json');
  const columnJson = fs.existsSync(columnFile) ? require(columnFile) : null;
  const library = columnJson ? columnJson.columnConfig.UUID : options.name;

  return {
    filenameHashing: false,
    configureWebpack: {
      externals: baseExternals,
      output: { libraryTarget: 'window', library },
      plugins: [
        new webpack.BannerPlugin({
          test: /\.(js|css)/,
          banner: `>>> built by ${gitUser} at ${builtTime}`
        }),
        new FiberSourceMapPlugin()
      ]
    },
    chainWebpack: (config) => {
      config.module
        .rule('images')
        .use('url-loader')
        .loader('url-loader')
        .tap((options) => Object.assign(options, { limit: 2000000 }));
    },
    css: { extract: false }
  };
}

// 获取git用户信息
function getGitUser() {
  try {
    const out = spawn.sync('git', ['config', 'user.email']);
    if (!out.status) return out.stdout.toString().replace(os.EOL, '');
    return '';
  } catch (ex) {
    return '';
  }
}

// 获取当前日期
function getTimeStr() {
  const d = new Date();
  return [
    [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('-'),
    [d.getHours(), d.getMinutes(), d.getSeconds()].join(':')
  ].join(' ');
}

const defaultConfig = {
  port: 3000,
  proxyServer: 'http://a82.seeyoncd.com',
  useFiber: true
};

module.exports = (userConfig = defaultConfig) => {
  userConfig = userConfig || {};
  userConfig = {
    ...defaultConfig,
    ...userConfig
  };
  if (isLib && !isDev) {
    return genLibProdConfig(userConfig);
  }
  return genAppConfig(userConfig);
};
